package com.jcxh.sg_exam.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jcxh.sg_exam.pojo.*;
import com.jcxh.sg_exam.pojo.dto.AddUserDto;
import com.jcxh.sg_exam.pojo.dto.AdminDto;
import com.jcxh.sg_exam.pojo.dto.UpdateUserDto;
import com.jcxh.sg_exam.service.*;
import com.jcxh.sg_exam.utils.BCrypt;
import com.jcxh.sg_exam.utils.IDUtils;
import com.jcxh.sg_exam.utils.PhoneUtil;
import com.jcxh.sg_exam.utils.RedisCacheService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Author 鹏少
 * @Date 2024/8/6
 * @Date 14:28
 */
@Api(tags = "管理端接口")
@RestController
@RequestMapping("/admin")
@Slf4j
public class AdminController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private UserService userService;

    @Autowired
    private KaochangUserService kaochangUserService;

    @Autowired
    private KaochangService kaochangService;

    @Autowired
    private UserTitleService userTitleService;

    @Autowired
    private RedisCacheService redisCacheService;

    /**
     * 管理端登录接口
     *
     * @param admindto
     * @return
     */
    @ApiOperation(value = "管理端用户登录接口")
    @PostMapping("/login")
    public Result adminLogin(@RequestBody AdminDto admindto) {

        return adminService.login(admindto);

    }


    /**
     * 管理端注册接口
     *
     * @param admindto
     * @return
     */
    @ApiOperation(value = "管理端用户注册接口")
    @PostMapping("/register")
    public Result adminRegister(@RequestBody AdminDto admindto) {

        return adminService.register(admindto);

    }


    /**
     * 人员信息查询
     *
     * @param name
     * @param idNumber
     * @param workUnit
     * @return
     */
    @ApiOperation(value = "查询人员信息")
    @GetMapping("/queryUsers")
    public Result getAll(
            @ApiParam(value = "当前页码", required = true) @RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
            @ApiParam(value = "每页大小(后端默认为10)", required = true) @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            @ApiParam(value = "姓名") String name, @ApiParam(value = "身份证号") String idNumber, @ApiParam(value = "工作单位") String workUnit) {

        IPage<User> page = new Page<>(currentPage, pageSize);
        IPage<User> userIPage = userService.lambdaQuery()
                .select(User::getId, User::getName, User::getWorkUnit, User::getIdNumber, User::getPhone)
                .like(name != null, User::getName, name)
                .like(idNumber != null, User::getIdNumber, idNumber)
                .like(workUnit != null, User::getWorkUnit, workUnit)
                .orderByAsc(User::getId)
                .page(page);


        return Result.success(userIPage);
    }


    /**
     * 新增人员
     *
     * @param addUserDto
     * @return
     */
    @ApiOperation(value = "新增人员")
    @PostMapping("/addUser")
    public Result addUser(@ApiParam(value = "新增人员实体类", required = true) @Valid @RequestBody AddUserDto addUserDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            // 如果有验证错误，返回具体的错误信息
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
//            String errorMessages = fieldErrors.stream()
//                    .map(fieldError -> fieldError.getField() + ": " + fieldError.getDefaultMessage())
//                    .collect(Collectors.joining(", "));
            String errorMessages = fieldErrors.stream()
                    .map(fieldError -> fieldError.getDefaultMessage())
                    .collect(Collectors.joining(", "));
            return Result.error("验证失败：" + errorMessages);
        }

        String idNumber = addUserDto.getIdNumber();
        boolean isIdNumberValid = IDUtils.isIDNumber(idNumber);
        if (!isIdNumberValid) {
            return Result.error("身份证格式不对，请重新输入");
        }
        String phone = addUserDto.getPhone();
        boolean mobileNumber = PhoneUtil.isMobileNumber(phone);
        if (!mobileNumber) {
            return Result.error("手机号格式不对，请重新输入");
        }

        User existingUser = userService.lambdaQuery()
                .eq(User::getIdNumber, idNumber)
                .one();
        if (existingUser != null) {
            return Result.error("该人员已经存在，请勿重复添加");
        }

        User user = new User();
        BeanUtils.copyProperties(addUserDto, user);
        String gensalt = BCrypt.gensalt(10); // 考虑将盐值存储到配置中或数据库中
        user.setPassword(BCrypt.hashpw("123456", gensalt));//密码默认123456
        userService.save(user);
        //将新增人员存入redis中 以供应后续用户端登录操作减少数据库查询
        redisCacheService.set(user.getIdNumber(), JSON.toJSONString(user));
        return Result.success("添加成功");
    }


    @Transactional
    @DeleteMapping("/deleteUser")
    @ApiOperation(value = "删除人员")
    public Result deleteUser(@ApiParam(value = "要删除人员的id", required = true) @RequestParam List<Integer> ids) {
        if (ids.isEmpty()) {
            return Result.error("删除列表为空，请选择要删除的人员");
        }
        List<User> userList = userService.lambdaQuery().in(User::getId, ids).list();
        try {
            userService.removeByIds(ids);
            List<KaochangUser> list = kaochangUserService.lambdaQuery().in(KaochangUser::getUserId, ids).list();
            Map<String, Long> nameCountMap = list.stream()
                    .map(s -> s.getKaochangName())
                    .collect(Collectors.groupingBy(name -> name, Collectors.counting()));
            log.info("---{}",nameCountMap);
            kaochangUserService.removeByUserId(ids);

            userTitleService.removeByUserId(ids);
            // 批量更新考场总数
            nameCountMap.forEach((name, count) ->
                    kaochangService.lambdaUpdate()
                            .setSql("total = total - " + count)
                            .eq(Kaochang::getName, name)
                            .update()
            );

        } catch (Exception e) {
            // 记录日志
            // log.error("删除人员失败", e);
            return Result.error("删除操作失败，请稍后重试");
        }

        //将人员在redis中删除 以供应后续用户端登录操作减少数据库查询
        for (User user : userList) {
            redisCacheService.delete(user.getIdNumber());
        }
        return Result.success("删除成功");
    }

    @Transactional
    @PutMapping("/updateUser")
    @ApiOperation(value = "修改人员信息")
    public Result updateUser(@ApiParam(value = "修改人员实体类", required = true)
                             @Valid @RequestBody UpdateUserDto userDto, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            // 如果有验证错误，返回具体的错误信息
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
//            String errorMessages = fieldErrors.stream()
//                    .map(fieldError -> fieldError.getField() + ": " + fieldError.getDefaultMessage())
//                    .collect(Collectors.joining(", "));
            String errorMessages = fieldErrors.stream()
                    .map(fieldError -> fieldError.getDefaultMessage())
                    .collect(Collectors.joining(", "));
            return Result.error("验证失败：" + errorMessages);
        }

        String idNumber = userDto.getIdNumber();
        boolean isIdNumberValid = IDUtils.isIDNumber(idNumber);
        if (!isIdNumberValid) {
            return Result.error("身份证格式不对，请重新输入");
        }
        String phone = userDto.getPhone();
        boolean mobileNumber = PhoneUtil.isMobileNumber(phone);
        if (!mobileNumber) {
            return Result.error("手机号格式不对，请重新输入");
        }
        boolean isIdNumberDuplicated = userService.lambdaQuery()
                .eq(User::getIdNumber, idNumber)
                .ne(User::getId, userDto.getId()) // 排除当前正在更新的用户
                .count() > 0;

        if (isIdNumberDuplicated) {
            return Result.error("身份证号码重复");
        }

        //删除redis中旧的数据
        User user = userService.lambdaQuery().eq(User::getId, userDto.getId()).one();
        redisCacheService.delete(user.getIdNumber());

        boolean update = userService.lambdaUpdate().set(User::getName, userDto.getName())
                .set(User::getWorkUnit, userDto.getWorkUnit())
                .set(User::getIdNumber, userDto.getIdNumber())
                .set(User::getPhone, userDto.getPhone())
                .eq(User::getId, userDto.getId()).update();

        boolean update1 = kaochangUserService.lambdaUpdate().set(KaochangUser::getName, userDto.getName())
                .set(KaochangUser::getWorkUnit, userDto.getWorkUnit())
                .set(KaochangUser::getIdNumber, userDto.getIdNumber())
                .set(KaochangUser::getPhone, userDto.getPhone())
                .eq(KaochangUser::getUserId, userDto.getId()).update();
        if (update) {
            //将修改人员存入redis中 以供应后续用户端登录操作减少数据库查询
            User updateUser = userService.lambdaQuery().eq(User::getId, userDto.getId()).one();
            redisCacheService.set(userDto.getIdNumber(), JSON.toJSONString(updateUser));
            return Result.success("修改成功");
        } else {
            return Result.error("修改失败");
        }

    }


    @GetMapping("/queryById")
    @ApiOperation(value = "根据id查询人员信息")
    public Result queryById(@ApiParam(value = "查询人员的id", required = true) @RequestParam Integer id) {
        User user = userService.lambdaQuery().eq(User::getId, id).one();
        user.setPassword("");
        return Result.success(user);
    }



}



